﻿using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using ApiScanner.Core;
using ApiScannerShell.Views;

namespace ApiScannerShell.ViewModels
{
    public sealed class ScannerConfigurationSectionViewModel: ViewModel<ScannerConfigurationSectionViewModel, ScannerConfigurationSection>
    {
        private TestConfigurationElementCollectionViewModelCollection _TestConfigurationElementCollectionViewModelCollection;
        private readonly IEnumerable<ICommand> _CreateTestActionCommands;

        private void CreateTest<T>()
            where T: TestConfigurationElement, new()
        {
            Tests.AddAndConfigure(new T());
        }

        private bool AllowOneTest<T>()
            where T : TestConfigurationElement, new()
        {
            return !Tests.Select(viewModel => viewModel.Model).OfType<T>().Any();
        }


        public ScannerConfigurationSectionViewModel(ScannerConfigurationSection model): base(model)
        {
            Model = model;
            _CreateTestActionCommands = new[]
            {
                new NamedDelegateCommand("Exchange store scanner", AllowOneTest<ExchangeStoreScannerTestConfigurationElement>, CreateTest<ExchangeStoreScannerTestConfigurationElement>),
                new NamedDelegateCommand("Filesystem scanner", CreateTest<FileSystemScannerTestConfigurationElement>),
                new NamedDelegateCommand("Smtp Event scanner", AllowOneTest<SmtpServerEventScannerTestConfigurationElement>, CreateTest<SmtpServerEventScannerTestConfigurationElement>),
            };
        }

  
        public TestConfigurationElementCollectionViewModelCollection Tests
        {
            get { return GetChildViewModel(v => v.Tests); }
        }

        public IEnumerable<ICommand> CreateTestActionCommands
        {
            get { return _CreateTestActionCommands.ToList(); }
        }

        protected override void ModelChanged()
        {
            _TestConfigurationElementCollectionViewModelCollection = new TestConfigurationElementCollectionViewModelCollection(Model.Tests);
            RegisterChildViewModel(v => v.Tests, _TestConfigurationElementCollectionViewModelCollection);
        }

        internal bool CanExecuteTests()
        {
            return Tests.Any(v => v.Model.IsEnabled);
        }

        internal void ExecuteTests()
        {
            SaveValuesToModel();
            var testRunner = new TestRunner(Model);
            var viewModel = new TestRunnerViewModel(testRunner);
            var view = new TestRunnerView(viewModel);
            view.ShowDialog();

        }
    }
}
